using System;
using System.Web.UI.WebControls;
using ClickSocial.Framework;
using TSHAK.Components;
using ICSharpCode.SharpZipLib.Zip;
using System.Data;
using System.IO;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Collections;

namespace ClickSocial.Admin
{
    public partial class FileManager1 : CDefault
    {
        protected string Dir;
        protected long space_current = 0;

        protected void Page_Load(object sender, EventArgs e)
        {
            //base.Page_Load(sender, e);

            if (!IsPostBack)
            {
                if (Request.QueryString["d"] != null)
                {
                    BindTree();
                    TreeView1.Nodes[0].Selected = true;
                    BindGrid();
                }
                else
                {
                    BindTree();
                }
            }

        }

        protected string GetFolderPath()
        {
            string dirpath = TreeView1.SelectedNode.ValuePath;
            string newpath = dirpath.Replace("~", "\\").Replace("|", " ").Replace("/", "\\");
            return newpath;
        }
        protected void ClearDg()
        {
            DataTable dt = CreateDataSource();
            dt.Clear();
            dgData.DataSource = dt;
            dgData.DataBind();
        }


        protected void btnDeleteFolder_Click(object sender, EventArgs e)
        {
            if (TreeView1.SelectedNode != null)
            {
                Directory.Delete(GetFolderPath(), true);
                BindTree();
                ClearDg();
            }
            else
            {
                lblError.Text = "Please select the folder";
            }

        }

        protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
        {
            BindGrid();

        }
        private void BindGrid()
        {
            DirectoryInfo dirinfo = new DirectoryInfo(GetFolderPath());
            FileInfo[] info = dirinfo.GetFiles();
            DataTable dt = CreateDataSource();
            DataRow dr;
            if (info.Length != 0)
            {
                foreach (FileInfo f in info)
                {
                    dr = dt.NewRow();
                    dr["filename"] = f.Name;
                    dr["size"] = (int)f.Length / 1024;
                    dr["type"] = "1";
                    dr["Date"] = DateTime.Parse(f.LastWriteTime.ToString()).ToString("MM/dd/yyyy");
                    dt.Rows.Add(dr);
                }
            }
            else
            {
                dt.Clear();
                lblCounter.Text = "";
                lblSpaceUsed.Text = "";
            }
            dgData.DataSource = dt;
            dgData.DataBind();
            lblError.Text = "";
            lblCounter.Text = dgData.Items.Count.ToString() + " object(s)";
            space_current = CalculateDirectorySize(new DirectoryInfo(string.Format("{0}\\{1}", BaseDir, Context.User.Identity.Name)), true);
            PerfilComun Perfil = Context.Profile as PerfilComun;
            if (space_current>(1024*1024))
                lblSpaceUsed.Text = string.Format("Used: {0:F}Mb de [{1}Mb]", (((float)space_current)/(1024*1024)), (Perfil.Espacio/1024/1024));
            else
                lblSpaceUsed.Text = string.Format("Used: {0}Kb de [{1}Mb]", (space_current / 1024), (Perfil.Espacio / 1024 / 1024));
        }

        private void BindTree()
        {
            TreeView1.Nodes.Clear();
            string rootFolder = User.IsInRole(Global.RolesApp.Host) ? BaseDir : string.Format("{0}\\{1}", BaseDir, Context.User.Identity.Name);
            TreeNode rootNode = new TreeNode();
            rootNode.Text = User.Identity.Name;
            rootNode.Expanded = true;
            rootNode.Value = rootFolder.Replace("\\", "~").Replace(" ", "|");
            TreeView1.Nodes.Add(rootNode);
            TreeView1.ShowLines = true;
            BuildTreeDirectory(rootFolder, rootNode);

        }
        private void BuildTreeDirectory(string dirPath, TreeNode parentNode)
        {
            string[] subDirectories = Directory.GetDirectories(dirPath);
            foreach (string directory in subDirectories)
            {
                string[] parts = directory.Split('\\');
                string name = parts[parts.Length - 1];
                TreeNode node = new TreeNode();
                if (User.IsInRole(Global.RolesApp.Fotografo))
                {
                    node.Text = ClickSocial.Components.Evento.GetOne(long.Parse(name)).Nombre;
                    node.Value = name;
                }
                else
                    node.Text = name; 
                node.ImageUrl = "~/images/folder.gif";
                node.Expanded = false;
                parentNode.ChildNodes.Add(node);
                BuildSubDirectory(directory, node);
            }

        }
        private void BuildSubDirectory(string dirPath, TreeNode parentNode)
        {
            string[] subDirectories = Directory.GetDirectories(dirPath);

            foreach (string directory in subDirectories)
            {
                string[] parts = directory.Split('\\');
                string name = parts[parts.Length - 1];
                TreeNode node = new TreeNode();
                if (User.IsInRole(Global.RolesApp.Host))
                {
                    node.Text = ClickSocial.Components.Evento.GetOne(long.Parse(name)).Nombre;
                    node.Value = name;
                }
                else
                    node.Text = name; 
                node.ImageUrl = "~/images/folder.gif";
                parentNode.ChildNodes.Add(node);
                node.Expanded = false;
                BuildSubDirectory(directory, node);
            }

        }

        protected void btnAddFolder_Click(object sender, EventArgs e)
        {
            lblError.Text = "";
            try
            {
                if (TreeView1.SelectedNode != null)
                {
                    if (txtAddFolder.Text != "")
                    {
                        Directory.CreateDirectory(Path.Combine(GetFolderPath(), Path.GetFileName(txtAddFolder.Text.Trim())));
                        ClearDg();
                        txtAddFolder.Text = "";
                        BindTree();
                    }
                    else
                    {
                        lblError.Text = "Please enter the folder name";
                    }
                }
                else
                {
                    lblError.Text = "Please select folder";
                }
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;

            }

        }

        protected void btnMoveFile_Click(object sender, EventArgs e)
        {
            Copy(true);
        }

        protected void btnUpload_Click(object sender, EventArgs e)
        {
            try
            {
                if (TreeView1.SelectedNode != null)
                {
                    if (TreeView1.SelectedNode.Text == User.Identity.Name)
                        throw new ApplicationException("No se permiten subir archivos al root de directorios.");

                    for (int i = 0; i < Request.Files.Count; i++)
                    {
                        if (Request.Files[i].FileName.Trim().Length > 0)
                        {
                            HttpPostedFile file = Request.Files[i];
                            if (file != null && file.FileName.Length > 0)
                            {
                                string ext = Path.GetExtension(file.FileName).ToLower();

                                if (ext != ".jpg" && ext != ".jpeg" && ext != ".gif" && ext != ".png")
                                    throw new ApplicationException("Solo se permiten tipos de imagenes (.jpg|.jpeg|.gif|.png).");

                                if (!CheckSpace(file.ContentLength))
                                    throw new Exception("Sin espacio disponible.");
                                
                                file.SaveAs(Path.Combine(GetFolderPath(), Path.GetFileName(file.FileName)));
                                
                            }
                        }
                    }
                    BindGrid();
                }
                else
                {
                    lblError.Text = "Please select folder";
                }


            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }
        }

        protected bool CheckSpace(long fileLength)
        {
            space_current = CalculateDirectorySize(new DirectoryInfo(string.Format("{0}\\{1}", BaseDir, Context.User.Identity.Name)), true);
            long new_space_used = fileLength + space_current;
            PerfilComun Perfil = Context.Profile as PerfilComun;
            return (Perfil.Espacio > new_space_used);
        }

        protected void dgData_ItemDataBound(object sender, DataGridItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.EditItem)
            {
                System.Web.UI.WebControls.LinkButton btnRename = (System.Web.UI.WebControls.LinkButton)e.Item.FindControl("btnRename");
                System.Web.UI.WebControls.LinkButton btnDelete = (System.Web.UI.WebControls.LinkButton)e.Item.FindControl("btnDelete");
                System.Web.UI.WebControls.ImageButton imgType = (System.Web.UI.WebControls.ImageButton)e.Item.FindControl("imgType");
                LinkButton edit = (LinkButton)e.Item.FindControl("btnEdit");
                Image download = (Image)e.Item.FindControl("btnDownload");
                LinkButton lnkName = (LinkButton)e.Item.FindControl("lnkName");

                SecureQueryString qs = new SecureQueryString();
                qs["Dir"] = GetCurDir() + "\\" + DataBinder.Eval(e.Item.DataItem, "filename");

                string name = System.Web.UI.DataBinder.Eval(e.Item.DataItem, "filename", "{0}").Trim().ToLower();

                if (name.Trim().ToLower().EndsWith(".txt"))
                {
                    imgType.ImageUrl = "~/Icons/file.gif";
                }
                else if (name.Trim().ToLower().EndsWith(".cs"))
                {
                    imgType.ImageUrl = "~/Icons/cs.gif";
                }
                else if (name.Trim().ToLower().EndsWith(".vb"))
                {
                    imgType.ImageUrl = "~/Icons/vb.gif";
                }
                else if (name.Trim().ToLower().EndsWith(".jpg"))
                {
                    imgType.ImageUrl = "~/Icons/jpg.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".gif"))
                {
                    imgType.ImageUrl = "~/Icons/gif.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".png"))
                {
                    imgType.ImageUrl = "~/Icons/png.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".bmp"))
                {
                    imgType.ImageUrl = "~/Icons/bmp.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".html") || name.Trim().ToLower().EndsWith(".htm"))
                {
                    imgType.ImageUrl = "~/Icons/html.jpg";
                }
                else if (name.Trim().ToLower().EndsWith(".asp") || name.Trim().ToLower().EndsWith(".aspx") || name.Trim().ToLower().EndsWith(".php"))
                {
                    imgType.ImageUrl = "~/Icons/aspx.gif";
                }
                else if (name.Trim().ToLower().EndsWith(".zip"))
                {
                    imgType.ImageUrl = "~/Icons/zip.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".doc"))
                {
                    imgType.ImageUrl = "~/Icons/doc.gif";
                }
                else if (name.Trim().ToLower().EndsWith(".ascx"))
                {
                    imgType.ImageUrl = "~/Icons/ascx.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".ppt"))
                {
                    imgType.ImageUrl = "~/Icons/ppt.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".css"))
                {
                    imgType.ImageUrl = "~/Icons/css.gif";
                    edit.Visible = false;

                }
                else if (name.Trim().ToLower().EndsWith(".js"))
                {
                    imgType.ImageUrl = "~/Icons/js.gif";
                    edit.Visible = false;
                }
                else if (name.Trim().ToLower().EndsWith(".mdb"))
                {
                    imgType.ImageUrl = "~/Icons/mdb.gif";
                    edit.Visible = false;
                }
                else
                {
                    imgType.ImageUrl = "~/Icons/file.gif";
                    edit.Visible = false;
                }
            }

        }
        protected void dgData_CancelCommand(object source, DataGridCommandEventArgs e)
        {
            dgData.EditItemIndex = -1;
            BindGrid();
        }
        protected void dgData_ItemCommand(object source, DataGridCommandEventArgs e)
        {
            if (e.CommandName == "Delete")
            {
                LinkButton lnkName = (LinkButton)e.Item.FindControl("lnkName");
                File.Delete(Path.Combine(GetFolderPath(), lnkName.Text));
                BindGrid();
            }

            if (e.CommandName == "Modify")
            {
                LinkButton lnkName = (LinkButton)e.Item.FindControl("lnkName");
                string fileExtension = Path.GetExtension(lnkName.Text);

                if (fileExtension.Trim().ToLower().Equals(".txt") || fileExtension.Trim().ToLower().Equals(".vb") || fileExtension.Trim().ToLower().Equals(".cs") || fileExtension.Trim().ToLower().Equals(".asp") || fileExtension.Trim().ToLower().Equals(".aspx") || fileExtension.Trim().ToLower().Equals(".doc") || fileExtension.Trim().ToLower().Equals(".html"))
                {
                    SecureQueryString sqs = new SecureQueryString();
                    sqs["Dir"] = GetFolderPath() + "\\" + lnkName.Text;
                    Response.Write("<SCRIPT>window.location.href='EditFileManager.aspx?id=" + sqs.ToString() + "'</SCRIPT>");

                }
                else
                {
                    lblError.Text = "Cannot edit the file";
                }

            }

            if (e.CommandName == "UnzipIt")
            {
                LinkButton lnkName = (LinkButton)e.Item.FindControl("lnkName");
                string fileExtension = Path.GetExtension(lnkName.Text);

                if (fileExtension.Trim().ToLower().Equals(".zip"))
                {
                    Unzipfile(lnkName.Text);
                }
            }
        }
        protected void Unzipfile(string pfileName)
        {
            string sfile = Path.Combine(GetCurDir(), pfileName);
            string dir_unzipped = pfileName.Split('.')[0];

            ZipInputStream s = new ZipInputStream(File.OpenRead(sfile));
            ZipEntry theEntry;
            DirectoryInfo di = new DirectoryInfo(GetCurDir() + "\\" + dir_unzipped);
            if (!di.Exists)
            {
                di.Create();
            }
            while ((theEntry = s.GetNextEntry()) != null)
            {
                string directoryName = Path.GetDirectoryName(theEntry.Name);
                string fileName = Path.GetFileName(theEntry.Name);

                if (theEntry.IsDirectory)
                {
                    Directory.CreateDirectory(GetCurDir() + "\\" + dir_unzipped + "\\" + directoryName);
                }

                if (fileName != String.Empty)
                {
                    FileStream streamWriter = File.Create(GetCurDir() + "\\" + dir_unzipped + "\\" + theEntry.Name);

                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }

                    streamWriter.Close();
                }
            }
            s.Close();
            BindGrid();
            lblError.Text = "File successfully unzipped into unzipped folder";

        }
        protected void dgData_EditCommand(object source, DataGridCommandEventArgs e)
        {
            dgData.EditItemIndex = e.Item.ItemIndex;
            LinkButton lnkName = (LinkButton)e.Item.FindControl("lnkName");
            ViewState["lastSelection"] = lnkName.Text;
            BindGrid();
        }
        protected void dgData_UpdateCommand(object source, DataGridCommandEventArgs e)
        {
            try
            {
                TextBox txtEditName = (TextBox)e.Item.FindControl("txtEditName");
                if (txtEditName.Text.Trim().Length < 1)
                    return;

                File.Move(Path.Combine(GetFolderPath(), Path.GetFileName(ViewState["lastSelection"].ToString())), Path.Combine(GetFolderPath(), Path.GetFileName(txtEditName.Text)));

                dgData.EditItemIndex = -1;
                BindGrid();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }

        }


        private void ShowBufferStatus()
        {
            string count = "0";
            string action = "";
            if (Session["copiedFiles"] != null && Session["copied"] != null)
            {
                count = ((Hashtable)Session["copiedFiles"]).Count.ToString();
                action = (((bool)Session["copied"]) ? " - Copied" : " - Cut");
            }
            if (count.Trim().Equals("0"))
            {
                lblError.Text = "Error, No File or Folders selected";
            }
            else
            {
                lblError.Text = count + " object(s) in a memory " + action;
            }
        }

        protected String GetCurDir()
        {
            object obj = ViewState["curDir"];
            if (obj == null)
            {
                if (Dir != null)
                {
                    return Dir;
                }
                else
                {
                    SetCurDir(BaseDir);
                    return BaseDir;
                }
            }
            else
            {
                return (string)obj;
            }
        }

        private void SetCurDir(string dir)
        {
            ViewState["curDir"] = dir;
        }

        protected DataTable CreateDataSource()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("filename", typeof(string));
            dt.Columns.Add("size", typeof(int));
            dt.Columns.Add("type", typeof(int));
            dt.Columns.Add("Date", typeof(string));
            return dt;
        }
        protected void btnCopyFile_Click(object sender, EventArgs e)
        {
            Copy(false);
        }
        protected void btnPasteFile_Click(object sender, EventArgs e)
        {
            Paste();
        }
        private void Copy(bool cut)
        {

            try
            {
                Hashtable ht = new Hashtable();
                foreach (DataGridItem dgi in dgData.Items)
                {
                    CheckBox chkChecked = (CheckBox)dgi.FindControl("chkChecked");
                    if (chkChecked.Checked)
                    {
                        LinkButton lnkName = (LinkButton)dgi.FindControl("lnkName");
                        int type = 1;
                        ht.Add(Path.Combine(GetFolderPath(), lnkName.Text), type.ToString());
                        Session["copiedFiles"] = ht;
                        Session["copied"] = !cut;
                    }
                }

                ShowBufferStatus();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }
        }
        private void Paste()
        {

            try
            {
                if (Session["copiedFiles"] != null && Session["copied"] != null)
                {
                    Hashtable ht = (Hashtable)Session["copiedFiles"];
                    bool copied = (bool)Session["copied"];

                    foreach (DictionaryEntry de in ht)
                    {
                        if (int.Parse(de.Value.ToString()) == 0)
                        {
                            Directory.CreateDirectory(Path.Combine(GetFolderPath(), Path.GetFileName(de.Key.ToString())));
                            CopyDirectory(de.Key.ToString(), Path.Combine(GetFolderPath(), Path.GetFileName(de.Key.ToString())));
                            if (!copied)
                            {
                                Directory.Delete(de.Key.ToString(), true);
                            }
                        }
                        else
                        {
                            string desFilename = Path.Combine(GetFolderPath(), Path.GetFileName(de.Key.ToString()));
                            FileInfo fileInfo = new FileInfo(de.Key.ToString());

                            if (CheckSpace(fileInfo.Length))
                            {
                                if (copied)
                                {
                                    File.Copy(de.Key.ToString(), desFilename, true);
                                }
                                else
                                {
                                    File.Move(de.Key.ToString(), desFilename);
                                }
                            }
                            else
                            {
                                BindGrid();
                                throw new Exception("No se ha completado la operacion por falta de espacio.");
                            }
                        }
                    }
                }
                BindGrid();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }

        }

        private void CopyDirectory(string from, string to)
        {

            DirectoryInfo inf = new DirectoryInfo(from);
            foreach (FileInfo fileinf in inf.GetFiles())
            {
                fileinf.CopyTo(Path.Combine(to, fileinf.Name));
            }
            foreach (DirectoryInfo newinf in inf.GetDirectories())
            {
                Directory.CreateDirectory(Path.Combine(to, Path.GetFileName(newinf.FullName)));
                CopyDirectory(newinf.FullName, Path.Combine(to, Path.GetFileName(newinf.FullName)));
            }

        }
        private void DeleteItem(DataGridItem e)
        {
            LinkButton lnkName = (LinkButton)e.FindControl("lnkName");
            File.Delete(Path.Combine(GetFolderPath(), lnkName.Text));
        }
        protected void btnRefresh_Click(object sender, EventArgs e)
        {
            if (dgData.Items.Count != 0)
            {
                dgData.EditItemIndex = -1;
                BindGrid();
            }
        }
        protected void btnDeleteFile_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (DataGridItem dgi in dgData.Items)
                {
                    CheckBox chkChecked = (CheckBox)dgi.FindControl("chkChecked");
                    if (chkChecked.Checked)
                    {
                        DeleteItem(dgi);
                    }

                }
                BindGrid();
            }

            catch (Exception ex)
            {
                lblError.Text = ex.Message;
            }

        }

        static public long CalculateDirectorySize(DirectoryInfo directory, bool includeSubdirectories)
        {
            long totalSize = 0;

            // Examine all contained files.
            FileInfo[] files = directory.GetFiles();
            foreach (FileInfo file in files)
            {
                totalSize += file.Length;
            }

            // Examine all contained directories.
            if (includeSubdirectories)
            {
                DirectoryInfo[] dirs = directory.GetDirectories();
                foreach (DirectoryInfo dir in dirs)
                {
                    totalSize += CalculateDirectorySize(dir, true);
                }
            }

            return totalSize;
        }

    }
}
